﻿using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
using WssEvents;
using WssUtils;

namespace JQMergeFramework
{
    public class GameCameraControl : MonoBehaviour
    {
        
        [Header("拖动灵敏度")]
        private float _sensitivity = 2.0f;

        // public Transform _target;

        public static GameCameraControl I;
        
        
        //相机总是距离棋盘Y的距离

        private float chessboardDistanceY = 183;
        private float chessboardDistanceZ = -115;
        
        private float overDistanceY = 133;
        
        //相机起始高度
        private const float startCameraY = 50;
        
        private Vector3 animStartPos;
        
        //游戏视野值
        private float gameFieldOfView = 32.5f;
        
        //相机正视前方时的视野值
        private float frontFieldOfView = 110;

        //相机移动时间控制
        private float moveUpTimeV = 200;
        
        //相机默认旋转
        private Vector3 defaultRotate = new Vector3(55,0,0);

        //相机适配距离,记录一下相机适配移动的距离
        public float fitDes =0;

        public Camera mCamera;

        public float GetOffsetCameraPosY
        {
            get { return this.transform.position.y - chessboardDistanceY; }
        }

        //相机移动视野偏移
        private float cameraOffsetY = 30.0F;
        private void Awake()
        {
            I = this;
            
            mCamera = this.GetComponent<Camera>();

            float f = CommonFun.GetScreenRatio();
            
            fitDes = Vector3.Distance(new Vector3(0, chessboardDistanceY, chessboardDistanceZ),
                new Vector3(0, chessboardDistanceY * f, chessboardDistanceZ * f));
            
     
           chessboardDistanceY = chessboardDistanceY * f;
           chessboardDistanceZ = chessboardDistanceZ * f;
           animStartPos = new Vector3(chessboardDistanceZ, startCameraY, chessboardDistanceZ);
        }

        private void Start()
        {
            //初始化塔吊
            TowerControl.I.InitTower();
       
            
            StartAnim();
            
            AudioManager.Instance.PlayBGM(AudioName.GameBGM);
        }


        #region 开始动画

        /// <summary>
        /// 开始动画
        /// </summary>
        void StartAnim()
        {
            //更新道具数量
            GlobalEvent.Dispatcher(GameEvents.OnRefreshProp);
            
            float height = MainCityControl.I.GetCityNodeHeight(false);

            UIManager.Instance.GetWindow<UIGame>(false);
            
            int estimate = (int)Math.Floor((height) / moveUpTimeV);
            estimate = estimate > 0 ? estimate : 1;

      
     
            
            this.transform.GetComponent<Camera>().fieldOfView = 120;
      
        

            Sequence sq = DOTween.Sequence();
            sq.Append(this.transform.GetComponent<Camera>().DOFieldOfView(90,1f));

            if (DataManager.Instance.BuildCityIdList.Count == 0)
            {
                //高度判断,开始点+相机距离高度
                List<Vector3> v3List =  PositionConvert.GetCirclePos(-Vector3.right, Vector3.zero, Math.Abs(chessboardDistanceZ),estimate*20,
                    height + chessboardDistanceY,startCameraY,180.0F,180,270);
                this.transform.position = v3List[0];
                this.transform.LookAt(Vector3.zero);
                sq.Append(this.transform.DOPath(v3List.ToArray(), 1, PathType.CatmullRom).OnUpdate(() =>
                {
                    transform.LookAt(Vector3.zero);
                }).SetEase(Ease.Linear));
            }
            else
            {
                //高度判断,开始点+相机距离高度
                List<Vector3> v3List =  PositionConvert.GetCirclePos(-Vector3.right, Vector3.zero, Math.Abs(chessboardDistanceZ),estimate*20,
                    height,startCameraY,180.0F,180,270);
                this.transform.position = v3List[0];
                this.transform.LookAt(Vector3.zero);
                sq.Append(this.transform.DOPath(v3List.ToArray(), height / moveUpTimeV, PathType.CatmullRom).OnUpdate(() =>
                {
                    transform.LookAt(new Vector3(0,transform.position.y-cameraOffsetY,0));
                }).SetEase(Ease.Linear));
            }
            

            sq.Append(this.transform.DOMoveY(height + chessboardDistanceY, 0.5f).SetEase(Ease.Linear));
            sq.Join(this.transform.DORotate(defaultRotate, 0.5f).SetEase(Ease.Linear));
            sq.Join(this.transform.GetComponent<Camera>().DOFieldOfView(gameFieldOfView,0.5F).SetEase(Ease.Linear));

            sq.OnComplete(() =>
            {
                //开始游戏
                GlobalEvent.Dispatcher(GameEvents.OnGameStart);
            });
            sq.Play();
        }

        #endregion

        #region 相机正视前方

        //相机震动\正视前方
        public void CameraMoveFront()
        {
            //相机旋转 
            //Vector3.Lerp(beginPosition, stopRotatePos, t);
            
            List<int> idList = DataManager.Instance.BuildCityIdList;
            float height = MainCityControl.I.GetCityNodeHeight(idList.Count-4,false);
            
            float dis = Vector3.Distance(this.transform.position, new Vector3(0, height, 0));

            height = height > startCameraY ? height : startCameraY;
            
            Sequence sq = DOTween.Sequence();
            sq.Append(this.transform.DOPunchRotation(new Vector3(0, 2, 2), 1, 5, 0).SetEase(Ease.InOutCubic));
            sq.Append(this.transform.GetComponent<Camera>().DOFieldOfView(40, 1F));
            sq.Append(this.transform.DOMove(new Vector3(0, height, chessboardDistanceZ), 1F).OnUpdate(() =>
            {
                this.transform.LookAt( new Vector3(0, height, 0));
            }));
            sq.Join(this.transform.GetComponent<Camera>().DOFieldOfView(frontFieldOfView, 1F));
            sq.Play();
        }
        #endregion


        #region 相机看向棋盘视角

        //相机看向棋盘，俯视角度
        public void CameraMoveLockAtChessboard()
        {
            float height = MainCityControl.I.GetCityNodeHeight(false);
            
            Sequence sq = DOTween.Sequence();
            sq.Append(this.transform.DOMove(new Vector3(0, height + (chessboardDistanceY), chessboardDistanceZ), 1f));
            
            // sq.Append( this.transform.DOMove(new Vector3(0, (height + chessboardDistanceY),chessboardDistanceZ), 0.5f));
            sq.Join(this.transform.GetComponent<Camera>().DOFieldOfView(gameFieldOfView,1));
            sq.Join(this.transform.DORotate(defaultRotate, 1));
            
            sq.Play();
        }
        #endregion

        #region 相机游戏失败动画

        /// <summary>
        /// 游戏失败，相机动画
        /// </summary>
        public void CameraFailAnim()
        {
            int count = CityBaseControl.I.cloneCityCount;
            
            float height = MainCityControl.I.GetCityNodeHeight(false);

            MergeManager mergeManager = MergeManager.Instance;
            
            int estimate = (int)Math.Floor((height+chessboardDistanceY) / moveUpTimeV);
            estimate = estimate > 0 ? estimate : 1;
            
            //隐藏UI
            UIManager.Instance.GetWindow<UIGame>(false);
            
            List<Vector3> v3List =  PositionConvert.GetCirclePos(-Vector3.right, Vector3.zero , 
                Math.Abs(chessboardDistanceZ),estimate*20,
                (height+overDistanceY),startCameraY,310.0F,270F,40);
            
            Sequence sq = DOTween.Sequence();
            
            RoofUnit roofUnit = Instantiate(mergeManager.scriptablePrefab.capping,CityBaseControl.I.bigCityParent).GetComponent<RoofUnit>();
            
            sq.AppendCallback(() =>
            {
                CityBaseControl.I.SetShowChessboard(false);
                //清空棋盘
                MergeManager.Instance.ClearCity();
                //清空塔吊的房子
                TowerControl.I.ClearTowerCity();
                TowerControl.I.ShowPlaceTipsEft(false);
            });
            
            if (DataManager.Instance.BuildCityIdList.Count > 0)
            {
                sq.Append(this.transform.DOMove(new Vector3(0, height, chessboardDistanceZ), 1).OnUpdate(() =>
                {
                    this.transform.LookAt(new Vector3(0, height, 0) );
                }));
                sq.Join(this.transform.GetComponent<Camera>().DOFieldOfView(frontFieldOfView, 0.5f));
                sq.AppendCallback(() =>
                {
                    TowerControl.I.SetShow(false);
                });
                sq.AppendInterval(0.2F);
                //相机下移
                sq.Append(this.transform.DOMoveY(startCameraY, height / 200).OnUpdate(() =>
                {
                    this.transform.LookAt(new Vector3(0, this.transform.position.y, 0) );
                }));
                
                //旋转上升
                sq.Append(this.transform.DOPath(v3List.ToArray(), (height+overDistanceY) / moveUpTimeV, PathType.CatmullRom).OnUpdate(() =>
                {
                    this.transform.LookAt(new Vector3(0,transform.position.y-cameraOffsetY,0));
                }));
            }
            
            
            sq.Append(this.transform.DORotate(new Vector3(35,0,0), 0.5f));
            sq.Join(this.transform.GetComponent<Camera>().DOFieldOfView(gameFieldOfView*2,0.5f));
            
            sq.AppendInterval(0.2F);
            sq.AppendCallback(() =>
            {
                roofUnit.SetShow(true);
                int startIndex = Mathf.FloorToInt(count/40.0F);
                startIndex = startIndex >= 5 ? startIndex % 5 : startIndex;
                if (startIndex == 3)
                {
                    roofUnit.SetMesh(mergeManager.scriptablePrefab.roofMeshList[0],new Vector3(0, height+50, 0));
                }
                else if (startIndex == 4)
                {
                    roofUnit.SetMesh(mergeManager.scriptablePrefab.roofMeshList[1],new Vector3(0, height+50, 0));
                }
                {
                    roofUnit.SetMesh(mergeManager.scriptablePrefab.roofMeshList[MyRandom.Range(0,2)],new Vector3(0, height+50, 0));
                }
            });
            sq.Append(roofUnit.transform.DOMoveY(height, 0.5F).SetEase(Ease.OutExpo));
            sq.AppendCallback(() =>
            {
                roofUnit.smoke.Play();
            });
            sq.Append(roofUnit.transform.DOPunchRotation(new Vector3(0, 0, 6), 0.7F, 5, 0).SetEase(Ease.OutQuad));
            sq.AppendCallback(() =>
            {
                //播放特效
                roofUnit.fireworks.Play();
            });
            sq.AppendInterval(0.5F);
            sq.AppendCallback(() =>
            {
                UIManager.Instance.GetWindow<UIClearingTips>().Open();
            });
            sq.Play();
        }
        #endregion

        private float y = -1;
        private void FixedUpdate()
        {
            float newY = this.transform.position.y;
            if (MathF.Abs(newY - y) > 1)
            {
                //启动楼层重复利用
                MainCityControl.I.UpdatePos();
                y = newY;
            }
        }
    }
}